package ar.edu.sovietrussia.customcomponents.searchbook;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;

import services.book.BookService;
import ar.edu.sovietrussia.customcomponents.bookviews.BookModel;
import ar.edu.sovietrussia.customcomponents.bookviews.BooksDataTable;
import ar.edu.sovietrussia.customcomponents.bookviews.DetailedBookViewPanel;
import ar.edu.sovietrussia.customcomponents.util.IDoReplaces;
import ar.edu.sovietrussia.customcomponents.util.IFeedbacker;
import ar.edu.sovietrussia.customcomponents.util.WrapperPanel;
import dtos.BookInfoDTO;

public abstract class MainSearchComponent extends Panel implements IFeedbacker, IDoReplaces {

    private static final long serialVersionUID = 1L;

    @SpringBean
    private BookService bookService;

    private Component searchPanel;

    private Component resultViewPanel;

    public MainSearchComponent(final String id) {
        super(id);
        this.initComponents();
        this.setOutputMarkupId(true);
    }

    private void initComponents() {
        // SEARCH PANEL
        SearchBookPanel search = new SearchBookPanel(this.getSearchComponentId(), new SearchBookPanelModel(), this) {
            private static final long serialVersionUID = 1L;

            @Override
            public void searchSubmited(final AjaxRequestTarget target) {
                MainSearchComponent.this.doSearchUpdate(this.getLastSearchResult(), target);
            }

            @Override
            protected FeedbackPanel getFeedbackTarget() {
                return MainSearchComponent.this.getFeedbackTarget();
            }
        };
        this.setSearchPanel(search);
        this.add(search);

        Component result = this.resultViewComponent(this.getResultsPanelId());
        this.setResultViewPanel(result);
        this.add(result);

        this.addTop20Link("linkTop");
        this.addNewBooksLink("newBooks");
    }

    private void addNewBooksLink(final String id) {
        AjaxLink<String> link = new AjaxLink<String>(id, Model.of("New books")) {

            private static final long serialVersionUID = 1L;

            @Override
            public void onClick(final AjaxRequestTarget target) {
                List<BookInfoDTO> topbooks = MainSearchComponent.this.getBookService().getNewBooksDTO(5);
                MainSearchComponent.this.doSearchUpdate(topbooks, target);
            }

        };
        this.add(link);
    }

    public Component resultViewComponent(final String id) {
        BooksDataTable result = new BooksDataTable(id, new ArrayList<BookInfoDTO>()) {
            private static final long serialVersionUID = 1L;

            @Override
            public void onDetailsLinkClicked(final BookInfoDTO book) {
                MainSearchComponent.this.onSelectedBook(new BookModel(book));
            }
        };
        return result;
    }

    private String getSearchComponentId() {
        return "searchPanel";
    }

    protected void doSearchUpdate(final List<BookInfoDTO> result, final AjaxRequestTarget target) {
        BooksDataTable panel = new BooksDataTable(this.getResultsPanelId(), result) {
            private static final long serialVersionUID = 1L;

            @Override
            public void onDetailsLinkClicked(final BookInfoDTO book) {
                MainSearchComponent.this.onSelectedBook(new BookModel(book));
            }
        };

        this.changeResultsPanel(panel);
        target.add(this);
    }

    private void addTop20Link(final String id) {
        AjaxLink<String> link = new AjaxLink<String>(id, Model.of("Top 20")) {

            private static final long serialVersionUID = 1L;

            @Override
            public void onClick(final AjaxRequestTarget target) {
                List<BookInfoDTO> topbooks = MainSearchComponent.this.getBookService().getTopBooksDTO(20);
                MainSearchComponent.this.doSearchUpdate(topbooks, target);
            }

        };
        this.add(link);
    }

    private void changeResultsPanel(final Panel panel) {
        this.getResultViewPanel().replaceWith(panel);
        this.setResultViewPanel(panel);
    }

    protected void onSelectedBook(final BookModel model) {
        DetailedBookViewPanel panel = new DetailedBookViewPanel(WrapperPanel.INTERNALID, model) {
            private static final long serialVersionUID = -1188880810288343297L;

            @Override
            public FeedbackPanel getFeedbackTarget() {
                return MainSearchComponent.this.getFeedbackTarget();
            }

            @Override
            public Map<String, WrapperPanel> getReplaceableComponents() {
                return MainSearchComponent.this.getReplaceableComponents();
            }
        };

        this.getReplaceableComponents().get("centerPanel").replace(panel);
    }

    public void setSearchPanel(final Component searchPanel) {
        this.searchPanel = searchPanel;
    }

    public Component getSearchPanel() {
        return this.searchPanel;
    }

    public void setResultViewPanel(final Component resultViewPanel) {
        this.resultViewPanel = resultViewPanel;
    }

    public Component getResultViewPanel() {
        return this.resultViewPanel;
    }

    public String getResultsPanelId() {
        return "booksResult";
    }

    public void setBookService(final BookService bookService) {
        this.bookService = bookService;
    }

    public BookService getBookService() {
        return this.bookService;
    }

}
